home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / varia / grammar1.lha / c++grammar1.1 / cpp4.y < prev    next >
GNU Bison Grammar  |  1990-06-06  |  71KB  |  1,833 lines

  1. %{
  2.  
  3.     /* Copyright (C) 1989,1990 James A. Roskind, All rights reserved.
  4.     This grammar was developed  and  written  by  James  A.  Roskind.
  5.     Copying  of  this  grammar  description, as a whole, is permitted
  6.     providing this notice is intact and applicable  in  all  complete
  7.     copies.   Translations as a whole to other parser generator input
  8.     languages  (or  grammar  description  languages)   is   permitted
  9.     provided  that  this  notice is intact and applicable in all such
  10.     copies,  along  with  a  disclaimer  that  the  contents  are   a
  11.     translation.   The reproduction of derived text, such as modified
  12.     versions of this grammar, or the output of parser generators,  is
  13.     permitted,  provided  the  resulting  work includes the copyright
  14.     notice "Portions Copyright (c)  1989,  1990  James  A.  Roskind".
  15.     Derived products, such as compilers, translators, browsers, etc.,
  16.     that  use  this  grammar,  must also provide the notice "Portions
  17.     Copyright  (c)  1989,  1990  James  A.  Roskind"  in   a   manner
  18.     appropriate  to  the  utility,  and in keeping with copyright law
  19.     (e.g.: EITHER displayed when first invoked/executed; OR displayed
  20.     continuously on display terminal; OR via placement in the  object
  21.     code  in  form  readable in a printout, with or near the title of
  22.     the work, or at the end of the file).  No royalties, licenses  or
  23.     commissions  of  any  kind are required to copy this grammar, its
  24.     translations, or derivative products, when the copies are made in
  25.     compliance with this notice. Persons or corporations that do make
  26.     copies in compliance with this notice may charge  whatever  price
  27.     is  agreeable  to  a  buyer, for such copies or derivative works.
  28.     THIS GRAMMAR IS PROVIDED ``AS IS'' AND  WITHOUT  ANY  EXPRESS  OR
  29.     IMPLIED  WARRANTIES,  INCLUDING,  WITHOUT LIMITATION, THE IMPLIED
  30.     WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR
  31.     PURPOSE.
  32.  
  33.     James A. Roskind
  34.     Independent Consultant
  35.     516 Latania Palm Drive
  36.     Indialantic FL, 32903
  37.     (407)729-4348
  38.     jar@ileaf.com
  39.     or ...!uunet!leafusa!jar
  40.  
  41.     ---end of copyright notice---
  42.  
  43. MOTIVATION-
  44.  
  45. My  goal  is  to  see  software  developers  adopt  this grammar as a
  46. standard until such time as a better  standard  is  accessible.   The
  47. only  way  to  get it to become a standard, is to be sure that people
  48. know that derivations are based on a specific work.   The  intent  of
  49. releasing  this  grammar is to provide a publicly accessible standard
  50. grammar for C++.  The intent of the  copyright  notice  is  to  allow
  51. arbitrary  commercial  and non-commercial use of the grammar, as long
  52. as reference is given to the original standard.  Without reference to
  53. a specific standard, many alternative  grammars  would  develop.   By
  54. referring  to  the  standard,  this grammar is given publicity, which
  55. should lead to further use in compatible products and  systems.   The
  56. benefits  of  such  a  standard  to  commercial  products  (browsers,
  57. beautifiers, translators, compilers, ...) should be  obvious  to  the
  58. developers,  in  that  other compatible products will emerge, and the
  59. value of all conforming products  will  rise.   Most  developers  are
  60. aware  of  the  value  of  acquiring  a fairly complete grammar for a
  61. language, and the copyright notice  (and  the  resulting  affiliation
  62. with my work) should not be too high a price to pay.  By copyrighting
  63. this  grammar,  I have some minor control over what this standard is,
  64. and I can (hopefully) keep it from degrading without my approval.   I
  65. will  consistently  attempt  to  provide  upgraded  grammars that are
  66. compliant  with  the  current  art,  and  the  ANSI   C++   Committee
  67. recommendation  in  particular.   A developer is never prevented from
  68. modifying the grammar to improve it in  whatever  way  is  seen  fit.
  69. There  is  also  no  restriction on the sale of copies, or derivative
  70. works, providing the request in the copyright notice are satisfied.
  71.  
  72. If you are not "copying" my work, but  are  rather  only  abstracting
  73. some  of  the  standard,  an acknowledgment with references to such a
  74. standard would be appreciated.  Specifically,  agreements  with  this
  75. standard  as  to  the  resolution  of otherwise ambiguous constructs,
  76. should be noted.
  77.  
  78. Simply put: "make whatever use you would like  of  the  grammar,  but
  79. include  the  ``portions  Copyright  ...''  as  a  reference  to this
  80. standard."
  81.  
  82.  
  83. */
  84.  
  85. /* File CPP4.Y is translated by YACC to y.tab.c
  86.                                 Version 1.1, last modified 5/25/90 */
  87.  
  88. /* ACKNOWLEDGMENT: Without Bjarne Stroustrup and his many  co-workers 
  89. at  Bell  Labs, there would be no C++ Language for which to provide a 
  90. syntax description. Bjarne has also been especially helpful and  open 
  91. in  discussions,  and  by  permitting me to review his texts prior to 
  92. their publication, allowed me a wonderful vantage point of clarity.
  93.  
  94. Without the effort expended by the ANSI C standardizing committee,  I 
  95. would  have been lost.  Although the ANSI C standard does not include 
  96. a fully disambiguated syntax description, the committee has at  least 
  97. provided  most  of  the disambiguating rules in narratives.  This C++ 
  98. grammar is intended to be a superset of an ANSI C compatible  grammar 
  99. that is provided in an related file.
  100.  
  101. Several  reviewers  have  also  recently  critiqued this grammar, the 
  102. related C  grammar,  and  or  assisted  in  discussions  during  it's 
  103. preparation.   These  reviewers are certainly not responsible for the 
  104. errors I have committed here, but they are responsible  for  allowing 
  105. me   to  provide  fewer  errors.   These  colleagues  include:  Bruce 
  106. Blodgett, Mark Langley, Joe Fialli, Greg Perkins, and Ron Guilmette.
  107. */ 
  108.  
  109. %}
  110.  
  111. /* Interesting ambiguity:
  112. Usually
  113.         typename ( typename2 ) ...
  114. or
  115.         typename ( typename2 [4] ) ...
  116. etc.
  117. is a redeclaration of typename2.
  118.  
  119. Inside a structure elaboration, it is sometimes the declaration of  a 
  120. constructor!   Note,  this  only  counts  if  typename IS the current 
  121. containing class name. (Note this can't conflict with ANSI C  because 
  122. ANSI  C  would  call  it a redefinition, but claim it is semantically 
  123. illegal because you can't have a member declared the same type as the 
  124. containing struct!) Since the ambiguity is only reached when a ';' is 
  125. found,  there  is  no  problem  with  the  fact  that  the   semantic 
  126. interpretation  is  providing  the  true  resolution.   As  currently 
  127. implemented, the constructor semantic actions must be able to process 
  128. an ordinary declaration.  I may reverse this in the future,  to  ease 
  129. semantic implementation. 
  130. */
  131.  
  132.  
  133.  
  134. /*
  135.  
  136. INTRO TO ANSI C GRAMMAR (provided in a separate file):
  137.  
  138. The refined grammar resolves several typedef ambiguities in the draft 
  139. proposed  ANSI  C standard syntax down to 1 shift/reduce conflict, as 
  140. reported by a YACC process.  Note that the one shift reduce conflicts 
  141. is the traditional if-if-else conflict that is not  resolved  by  the 
  142. grammar.  This ambiguity can be removed using the method described in 
  143. the  Dragon  Book  (2nd  edition), but this does not appear worth the 
  144. effort.
  145.  
  146. There was quite a bit of effort made to reduce the conflicts to  this 
  147. level,  and  an  additional effort was made to make the grammar quite 
  148. similar to the C++ grammar being developed in  parallel.   Note  that 
  149. this grammar resolves the following ANSI C ambiguities:
  150.  
  151. ANSI  C  section  3.5.6,  "If  the [typedef name] is redeclared at an 
  152. inner scope, the type specifiers shall not be omitted  in  the  inner 
  153. declaration".   Supplying type specifiers prevents consideration of T 
  154. as a typedef name in this grammar.  Failure to supply type specifiers 
  155. forced the use of the TYPEDEFname as a type specifier.  This is taken 
  156. to an (unnecessary) extreme by this implementation.  The ambiguity is 
  157. only a problem with the first declarator in  a  declaration,  but  we 
  158. restrict   ALL   declarators  whenever  the  users  fails  to  use  a 
  159. type.specifier.
  160.               
  161. ANSI C section 3.5.4.3, "In a parameter declaration, a single typedef 
  162. name in parentheses is  taken  to  be  an  abstract  declarator  that 
  163. specifies  a  function  with  a  single  parameter,  not as redundant 
  164. parentheses around the identifier".  This is extended  to  cover  the 
  165. following cases:
  166.  
  167. typedef float T;
  168. int noo(const (T[5]));
  169. int moo(const (T(int)));
  170. ...
  171.  
  172. Where  again the '(' immediately to the left of 'T' is interpreted as 
  173. being the start of a parameter type list,  and  not  as  a  redundant 
  174. paren around a redeclaration of T.  Hence an equivalent code fragment 
  175. is:
  176.  
  177. typedef float T;
  178. int noo(const int identifier1 (T identifier2 [5]));
  179. int moo(const int identifier1 (T identifier2 (int identifier3)));
  180. ...
  181.  
  182. */
  183.  
  184.  
  185. %{
  186. /*************** Includes and Defines *****************************/
  187. #define YYDEBUG_LEXER_TEXT (yylval) /* our lexer loads this up each time */
  188. #define YYDEBUG 1        /* Force the pretty debugging code to compile*/
  189. #define YYSTYPE  char *  /* interface with flex: should be in header file */
  190. /*************** Standard ytab.c continues here *********************/
  191. %}
  192.  
  193. /*************************************************************************/
  194.  
  195.  
  196.  
  197. %token AUTO            DOUBLE          INT             STRUCT
  198. %token BREAK           ELSE            LONG            SWITCH
  199. %token CASE            ENUM            REGISTER        TYPEDEF
  200. %token CHAR            EXTERN          RETURN          UNION
  201. %token CONST           FLOAT           SHORT           UNSIGNED
  202. %token CONTINUE        FOR             SIGNED          VOID
  203. %token DEFAULT         GOTO            SIZEOF          VOLATILE
  204. %token DO              IF              STATIC          WHILE
  205.  
  206. /* The following are used in C++ only.  ANSI C would call these IDENTIFIERs */
  207. %token NEW             DELETE
  208. %token THIS            
  209. %token OPERATOR
  210. %token CLASS           
  211. %token PUBLIC          PROTECTED       PRIVATE
  212. %token VIRTUAL         FRIEND
  213. %token INLINE          OVERLOAD        
  214.  
  215. /* ANSI C Grammar suggestions */
  216. %token IDENTIFIER              STRINGliteral
  217. %token FLOATINGconstant        INTEGERconstant        CHARACTERconstant
  218. %token OCTALconstant           HEXconstant
  219.  
  220. /* New Lexical element, whereas ANSI C suggested non-terminal */
  221. %token TYPEDEFname 
  222.  
  223. /* Multi-Character operators */
  224. %token  ARROW            /*    ->                              */
  225. %token  ICR DECR         /*    ++      --                      */
  226. %token  LS RS            /*    <<      >>                      */
  227. %token  LE GE EQ NE      /*    <=      >=      ==      !=      */
  228. %token  ANDAND OROR      /*    &&      ||                      */
  229. %token  ELLIPSIS         /*    ...                             */
  230.                  /* Following are used in C++, not ANSI C        */
  231. %token  CLCL             /*    ::                              */
  232. %token  DOTstar ARROWstar/*    .*       ->*                    */
  233.  
  234. /* modifying assignment operators */
  235. %token MULTassign  DIVassign    MODassign   /*   *=      /=      %=      */
  236. %token PLUSassign  MINUSassign              /*   +=      -=              */
  237. %token LSassign    RSassign                 /*   <<=     >>=             */
  238. %token ANDassign   ERassign     ORassign    /*   &=      ^=      |=      */
  239.  
  240.  
  241. /*************************************************************************/
  242.  
  243. %start prog.start
  244.  
  245. /*************************************************************************/
  246.  
  247. %%
  248. prog.start:
  249.         /*nothing*/
  250.         | translation.unit
  251.         ;
  252.  
  253. /* CONSTANTS */
  254. constant:
  255.         FLOATINGconstant
  256.         | INTEGERconstant
  257.         /*  We are not including ENUMERATIONconstant here because we
  258.           are treating it like a variable with a type of "enumeration
  259.           constant".  */
  260.         | OCTALconstant
  261.         | HEXconstant
  262.         | CHARACTERconstant
  263.         ;
  264.  
  265. /* STRING LITERALS */
  266. string.literal.list:
  267.                 STRINGliteral
  268.                 | string.literal.list STRINGliteral
  269.                 ;
  270.  
  271.  
  272. /* EXPRESSIONS */
  273.  
  274.     /* The following can be used in an identifier  based  declarator.  
  275.     (Declarators   that  redefine  an  existing  TYPEDEFname  require 
  276.     special handling, and are not included here).  In  addition,  the 
  277.     following are all valid "identifiers" in an expression, whereas a 
  278.     TYPEDEFname is NOT.*/
  279.     
  280. rescoped.identifier:
  281.         IDENTIFIER  /* ANSI C: We cannot use a TYPEDEFname as a variable */
  282.         | operator.function.name /* C++, not ANSI C*/
  283.         | class.rescoped.identifier
  284.         ;
  285.  
  286.  
  287.     /* When nested types are supported, an action must be taken prior 
  288.     to  the  CLCL  in each of the following productions to notify the 
  289.     lexer of a temporary change in scope. This change will allow  the 
  290.     lexer to deduce whether the name that follows the CLCL is that of 
  291.     an  IDENTIFIER  (member),  or  of a TYPEDEFname (locally declared 
  292.     type).  This lexical distinction is critical to continued  syntax 
  293.     analysis. */
  294.  
  295. class.rescoped.identifier:
  296.         TYPEDEFname CLCL identifier.or.typedef.name /* C++, not ANSI C */
  297.         | TYPEDEFname CLCL operator.function.name /* C++, not ANSI C */
  298.         | TYPEDEFname CLCL '~' TYPEDEFname /* C++, not ANSI C */
  299.         | TYPEDEFname CLCL class.rescoped.identifier /* C++, not ANSI C */
  300.         ;
  301.  
  302.     /* Note that the following MUST come before primary.expression so 
  303.     that  the  reduce/reduce conflict is properly resolved (according 
  304.     to Stroustrup: "If it can be a declaration, then it  should  be".  
  305.     I  just  give  up  and  go  in  that  direction  after  I see the 
  306.     declarator, whereas cfront tries to lex  ahead  to  disambiguate.  
  307.     My reduce-reduce conflict disambiguates this situation at a point 
  308.     where human readers cannot generally disambiguate (mentally). */
  309.     
  310. paren.identifier.declarator:
  311.         rescoped.identifier
  312.         | '(' paren.identifier.declarator ')'
  313.         ;
  314.  
  315.     /*  Note that CLCL IDENTIFIER is NOT part of rescoped.identifier. 
  316.     It is ONLY valid for referring to an identifier,  and  NOT  valid 
  317.     for  declaring  (or  importing  an  external  declaration  of) an 
  318.     identifier.  This disambiguates the following code,  which  would 
  319.     otherwise be syntactically and semantically ambiguous:
  320.  
  321.             class base {
  322.                 static int i; // element i;
  323.                 float member_funct(void);
  324.                 };
  325.             base i; // global i
  326.             float base::member_function(void) {
  327.                 i; // refers to static int element "i" of base
  328.                 ::i; // refers to global "i", with type "base"
  329.                     {
  330.                     base :: i; // import of global "i", like "base (::i);"?
  331.                                 // OR reference to global??
  332.                     }
  333.                 }
  334.         */
  335. primary.expression:
  336.         CLCL identifier.or.typedef.name  /* C++, not ANSI C */
  337.         | CLCL operator.function.name /* C++, not ANSI C */
  338.         | THIS   /* C++, not ANSI C */
  339.         | rescoped.identifier
  340.         | constant
  341.         | string.literal.list
  342.         | '(' expression ')'
  343.         ;
  344.  
  345.     /*  The  following  introduces  MANY  conflicts.   Requiring  and 
  346.     allowing '(' ')' around the `type' when the type is complex would 
  347.     help a lot. */
  348.  
  349. operator.function.name:
  350.         OPERATOR any.operator
  351.         | OPERATOR type.specifier.or.name  operator.function.ptr.opt
  352.         | OPERATOR type.qualifier.list     operator.function.ptr.opt
  353.         ;
  354.  
  355.     /* The following causes several ambiguities on *  and  &.   These 
  356.     conflicts  would also be removed if parens around the `type' were 
  357.     required in the derivations for operator.function.name */
  358.  
  359.     /*  Interesting  aside:  The  use  of  right  recursion  in   the 
  360.     production  for  operator.function.ptr.opt gives both the correct 
  361.     parsing, AND removes a conflict!   Right  recursion  permits  the 
  362.     parser   to   defer   reductions  (aka:  delay  resolution),  and 
  363.     effectively make a second pass! */
  364.         
  365. operator.function.ptr.opt:
  366.         /* nothing */
  367.         | pointer.operator operator.function.ptr.opt
  368.         | indirect.or.reference operator.function.ptr.opt
  369.         ;
  370.  
  371. any.operator:
  372.         '+'
  373.         | '-'
  374.         | '*'
  375.         | '/'
  376.         | '%'
  377.         | '^'
  378.         | '&'
  379.         | '|'
  380.         | '~'
  381.         | '!'
  382.         | '<'
  383.         | '>'
  384.         | LS
  385.         | RS
  386.         | ANDAND
  387.         | OROR
  388.         | ARROW
  389.         | ARROWstar
  390.         | '.' /* can we overload this? */
  391.         | DOTstar
  392.         | ICR
  393.         | DECR
  394.         | LE
  395.         | GE
  396.         | EQ
  397.         | NE
  398.         | assignment.operator
  399.         | '(' ')'
  400.         | '[' ']'
  401.         | NEW
  402.         | DELETE
  403.         | ','
  404.         ;
  405.  
  406.     /* The following production for type.qualifier.list was specially 
  407.     placed BEFORE the definition of postfix.expression to  resolve  a 
  408.     reduce-reduce conflict correctly */        
  409.  
  410. type.qualifier.list.opt:
  411.         /* Nothing */
  412.         | type.qualifier.list
  413.         ;
  414.  
  415.     /*  Note  that  the next set of productions in this grammar gives 
  416.     post-increment a higher precedence that pre-increment.   This  is 
  417.     not  clearly  stated  in  the  C++  Reference manual, and is only 
  418.     implied by the grammar in the ANSI C Standard. */
  419.  
  420. postfix.expression:
  421.         primary.expression
  422.         | postfix.expression '[' expression ']'
  423.         | postfix.expression '(' ')'
  424.         | postfix.expression '(' argument.expression.list ')'
  425.         | postfix.expression '.' rescoped.identifier.or.typedef.name
  426.         | postfix.expression ARROW rescoped.identifier.or.typedef.name
  427.         | postfix.expression ICR
  428.         | postfix.expression DECR
  429.  
  430.                 /* The next 4 rules are the source of cast ambiguity */
  431.         | TYPEDEFname '(' ')'
  432.         | TYPEDEFname '(' argument.expression.list ')'
  433.         | basic.type.name '(' assignment.expression ')'
  434.                 /* If the following rule is added to the grammar, there will
  435.                 be 3 additional reduce-reduce conflicts.  They will all be
  436.                 resolved in favor of NOT using the following rule, so no harm
  437.                 will be done.  However, since the rule is semantically
  438.                 illegal we will omit it until we are enhancing the grammar
  439.                 for error recovery */
  440. /*      | basic.type.name '(' ')'  Illegal: no such constructor*/
  441.         ;
  442.  
  443. rescoped.identifier.or.typedef.name:
  444.         TYPEDEFname 
  445.         | rescoped.identifier
  446.         ;
  447.  
  448. argument.expression.list:
  449.         assignment.expression
  450.         | argument.expression.list ',' assignment.expression
  451.         ;
  452.  
  453. unary.expression:
  454.         postfix.expression
  455.         | ICR unary.expression
  456.         | DECR unary.expression
  457.         | indirect.or.reference cast.expression
  458.         | '-' cast.expression
  459.         | '+' cast.expression
  460.         | '~' cast.expression
  461.         | '!' cast.expression
  462.         | SIZEOF unary.expression
  463.         | SIZEOF '(' type.name ')'
  464.         | allocation.expression
  465.         ;
  466.  
  467.  
  468.     /* Note that I could have moved the  newstore  productions  to  a 
  469.     lower  precedence  level  than  multiplication  (binary '*'), and 
  470.     lower than bitwise AND (binary '&').  These moves  are  the  nice 
  471.     way  to  disambiguate a trailing unary '*' or '&' at the end of a 
  472.     freestore expression.  Since the freestore expression (with  such 
  473.     a  grammar  and  hence  precedence  given)  can never be the left 
  474.     operand of a binary '*' or '&', the ambiguity would  be  removed.  
  475.     These  problems  really  surface when the binary operators '*' or 
  476.     '&' are overloaded, but this must be syntactically  disambiguated 
  477.     before the semantic checking is performed...  Unfortunately, I am 
  478.     not  creating  the language, only writing a grammar that reflects 
  479.     its specification, and  hence  I  cannot  change  its  precedence 
  480.     assignments.   If  I  had  my  druthers,  I would probably prefer 
  481.     surrounding the type with parens all the time, and  avoiding  the 
  482.     dangling * and & problem all together.*/
  483.  
  484.        /* Following are C++, not ANSI C */
  485. allocation.expression:
  486.         operator.new                                  '(' type.name ')'
  487.                 operator.new.initializer.opt
  488.         | operator.new '(' argument.expression.list ')' '(' type.name ')'
  489.                 operator.new.initializer.opt
  490.                 /* next two rules are the source of * and & ambiguities */
  491.         | operator.new                                  operator.new.type
  492.         | operator.new '(' argument.expression.list ')' operator.new.type
  493.         ;
  494.  
  495. operator.new:
  496.         NEW
  497.         | CLCL NEW
  498.         ;
  499.  
  500.     /*  Note:  the  otherwise  "silly" inline expansion in the next 4 
  501.     productions is necessary to allow such expressions as:
  502.  
  503.       new const T :: * ;
  504.       new const T ;
  505.  
  506.     to be parsed correctly.  */
  507.  
  508. operator.new.type:
  509.         type.qualifier.list      operator.new.declarator.opt
  510.                         operator.new.initializer.opt
  511.         | type.specifier.or.name operator.new.declarator.opt
  512.                         operator.new.initializer.opt
  513.         ;
  514.  
  515.     /* Perhaps I should move  the  following  to  a  more  consistent 
  516.     position, but for now I will just leave it here. */
  517.  
  518.     /*  Note that the following does not include type.qualifier.list. 
  519.     Hence, whenever type.specifier.or.name is used, an adjacent  rule 
  520.     is  supplied containing type.qualifier.list.  It is not generally 
  521.     possible    to    know    immediately    (i.e.,     reduce)     a 
  522.     type.qualifier.list,  as  a TYPEDEFname that follows might not be 
  523.     part of a type specifier, but might instead  be  "TYPEDEFname  :: 
  524.     *". */
  525.  
  526. type.specifier.or.name:
  527.         type.specifier
  528.         | basic.type.name
  529.         | TYPEDEFname
  530.         ;
  531.  
  532.     /*  Right  recursion  is critical in the following productions to 
  533.     avoid a conflict on TYPEDEFname */
  534.  
  535. operator.new.declarator.opt:
  536.         /* Nothing */
  537.         | operator.new.array.declarator
  538.         | indirect.or.reference operator.new.declarator.opt
  539.         | pointer.operator      operator.new.declarator.opt
  540.         ;
  541.  
  542. operator.new.array.declarator:
  543.         '[' ']'
  544.         | '[' expression ']'
  545.         | operator.new.array.declarator '[' expression ']'
  546.         ;
  547.  
  548. operator.new.initializer.opt:
  549.         /* Nothing */
  550.         | '(' ')'
  551.         | '(' argument.expression.list ')'
  552.         ;
  553.  
  554. cast.expression:
  555.         unary.expression
  556.         | '(' type.name ')' cast.expression
  557.         ;
  558.  
  559.     /* Following are C++, not ANSI C */
  560. deallocation.expression:
  561.         cast.expression
  562.         | clcl.opt.delete deallocation.expression
  563.         | clcl.opt.delete '[' expression ']' deallocation.expression  /* archaic */
  564.         | clcl.opt.delete '[' ']' deallocation.expression
  565.         ;
  566.  
  567.     /* Following are C++, not ANSI C */
  568. clcl.opt.delete:
  569.         DELETE
  570.         | CLCL DELETE
  571.         ;
  572.  
  573.     /* Following are C++, not ANSI C */
  574. point.member.expression:
  575.         deallocation.expression
  576.         | point.member.expression DOTstar  deallocation.expression
  577.         | point.member.expression ARROWstar  deallocation.expression
  578.         ;
  579.         
  580. multiplicative.expression:
  581.         point.member.expression
  582.         | multiplicative.expression '*' point.member.expression
  583.         | multiplicative.expression '/' point.member.expression
  584.         | multiplicative.expression '%' point.member.expression
  585.         ;
  586.  
  587. additive.expression:
  588.         multiplicative.expression
  589.         | additive.expression '+' multiplicative.expression
  590.         | additive.expression '-' multiplicative.expression
  591.         ;
  592.  
  593. shift.expression:
  594.         additive.expression
  595.         | shift.expression LS additive.expression
  596.         | shift.expression RS additive.expression
  597.         ;
  598.  
  599. relational.expression:
  600.         shift.expression
  601.         | relational.expression '<' shift.expression
  602.         | relational.expression '>' shift.expression
  603.         | relational.expression LE shift.expression
  604.         | relational.expression GE shift.expression
  605.         ;
  606.  
  607. equality.expression:
  608.         relational.expression
  609.         | equality.expression EQ relational.expression
  610.         | equality.expression NE relational.expression
  611.         ;
  612.  
  613. AND.expression:
  614.         equality.expression
  615.         | AND.expression '&' equality.expression
  616.         ;
  617.  
  618. exclusive.OR.expression:
  619.         AND.expression
  620.         | exclusive.OR.expression '^' AND.expression
  621.         ;
  622.  
  623. inclusive.OR.expression:
  624.         exclusive.OR.expression
  625.         | inclusive.OR.expression '|' exclusive.OR.expression
  626.         ;
  627.  
  628. logical.AND.expression:
  629.         inclusive.OR.expression
  630.         | logical.AND.expression ANDAND inclusive.OR.expression
  631.         ;
  632.  
  633. logical.OR.expression:
  634.         logical.AND.expression
  635.         | logical.OR.expression OROR logical.AND.expression
  636.         ;
  637.  
  638. conditional.expression:
  639.         logical.OR.expression
  640.         | logical.OR.expression '?' expression ':'
  641.                 conditional.expression
  642.         ;
  643.  
  644. assignment.expression:
  645.         conditional.expression
  646.         | unary.expression assignment.operator assignment.expression
  647.         ;
  648.  
  649. assignment.operator:
  650.         '='
  651.         | MULTassign
  652.         | DIVassign
  653.         | MODassign
  654.         | PLUSassign
  655.         | MINUSassign
  656.         | LSassign
  657.         | RSassign
  658.         | ANDassign
  659.         | ERassign
  660.         | ORassign
  661.         ;
  662.  
  663. expression:
  664.         assignment.expression
  665.         | expression ',' assignment.expression
  666.         ;
  667.  
  668. constant.expression:
  669.         conditional.expression
  670.         ;
  671.  
  672.     /* The following was used for clarity */
  673. expression.opt:
  674.         /* Nothing */
  675.         | expression
  676.         ;
  677.  
  678.  
  679.  
  680. /* DECLARATIONS */
  681.  
  682.     /* The following are notably different from the ANSI  C  Standard 
  683.     specified  grammar,  but  are  present  in  my  ANSI C compatible 
  684.     grammar.  The changes were made to disambiguate typedefs presence 
  685.     in   declaration.specifiers   (vs.    in   the   declarator   for 
  686.     redefinition);  to allow struct/union/enum/class tag declarations 
  687.     without  declarators,  and  to  better  reflect  the  parsing  of 
  688.     declarations     (declarators     must     be    combined    with 
  689.     declaration.specifiers ASAP, so that they can immediately  become 
  690.     visible in the current scope). */
  691.  
  692. declaration:
  693.         sue.declaration.specifier ';' { /* this is semantic error, as it
  694.                                         includes a storage class!?!*/ }
  695.         | sue.type.specifier ';'
  696.         | declaring.list ';'
  697.         | default.declaring.list ';'
  698.         ;
  699.  
  700.     /*  Note  that  if  a typedef were redeclared, then a declaration 
  701.     specifier must be supplied (re: ANSI C spec).  The following  are 
  702.     declarations  wherein  no  declaration.specifier is supplied, and 
  703.     hence the 'default' must be used.  An example of this is
  704.  
  705.         const a;
  706.  
  707.     which by default, is the same as:
  708.  
  709.         const int a;
  710.  
  711.     `a' must NOT be a typedef in the above example. */
  712.  
  713.  
  714.     /* The presence of `{}' in the following rules  indicates  points 
  715.     at  which  the symbol table MUST be updated so that the tokenizer 
  716.     can IMMEDIATELY  continue  to  maintain  the  proper  distinction 
  717.     between a TYPEDEFname and an IDENTIFIER. */
  718.     
  719.  
  720. default.declaring.list:  /* Can't  redeclare typedef names */
  721.         declaration.qualifier.list   identifier.declarator {} initializer.opt
  722.         | type.qualifier.list        identifier.declarator {} initializer.opt
  723.         | default.declaring.list ',' identifier.declarator {} initializer.opt
  724.  
  725.         | declaration.qualifier.list constructed.identifier.declarator
  726.         | type.qualifier.list        constructed.identifier.declarator
  727.         | default.declaring.list ',' constructed.identifier.declarator
  728.         ;
  729.  
  730.     /*  Note  how  type.qualifier.list  is  NOT used in the following 
  731.     productions.   Qualifiers  are   NOT   sufficient   to   redefine 
  732.     typedef-names (as prescribed by the ANSI C standard).*/
  733.     
  734. declaring.list:
  735.         declaration.specifier  declarator {} initializer.opt
  736.         | type.specifier       declarator {} initializer.opt
  737.         | basic.type.name      declarator {} initializer.opt
  738.         | TYPEDEFname          declarator {} initializer.opt
  739.         | declaring.list ','   declarator {} initializer.opt
  740.  
  741.         | declaration.specifier constructed.declarator
  742.         | type.specifier        constructed.declarator
  743.         | basic.type.name       constructed.declarator
  744.         | TYPEDEFname           constructed.declarator
  745.         | declaring.list ','    constructed.declarator
  746.         ;
  747.  
  748.     /*  Declarators  with  parenthesized  initializers  present a big 
  749.     problem.  Typically a declarator that looks  like:  "*a(...)"  is 
  750.     supposed  to bind FIRST to the "(...)", and then to the "*". This 
  751.     binding presumes that the "(...)" stuff  is  a  prototype  scope.  
  752.     With  constructed  declarators,  we  must (officially) finish the 
  753.     binding to the "*" (finishing forming a good declarator) and THEN 
  754.     connect with the argument list.  Unfortunately, by  the  time  we 
  755.     realize  it  is  an  argument  list (and not a prototype) we have 
  756.     pushed the separate declarator tokens "*a" onto  the  yacc  stack 
  757.     WITHOUT combining them. The solution is to use odd productions to 
  758.     carry   the   incomplete  declarator  along  with  the  "argument 
  759.     expression list" back up the yacc stack.  We would then  actually 
  760.     instantiate  the  symbol  table after we have fully decorated the 
  761.     symbol with all the leading "*" stuff. Actually, since  we  don't 
  762.     have  all  the  type  information in one spot till we reduce to a 
  763.     declaring.list, this delay is not a problem.  Note that  ordinary 
  764.     initializers  REQUIRE (ANSI C Standard) that the symbol be placed 
  765.     into the symbol table BEFORE its initializer is read, but in  the 
  766.     case  of  parenthesized  initializers,  this  is not possible (we 
  767.     don't even know we have  an  initializer  till  have  passed  the 
  768.     opening "(". )*/
  769.  
  770. constructed.declarator:
  771.         nonunary.constructed.identifier.declarator
  772.         | constructed.paren.typedef.declarator 
  773.         | simple.paren.typedef.declarator '(' argument.expression.list ')'  
  774.         | simple.paren.typedef.declarator postfixing.abstract.declarator 
  775.                                           '(' argument.expression.list ')'  /* semantic error*/
  776.         | constructed.parameter.typedef.declarator 
  777.         | indirect.or.reference constructed.declarator
  778.         | pointer.operator      constructed.declarator
  779.         ;
  780.  
  781. constructed.paren.typedef.declarator:
  782.         '(' paren.typedef.declarator ')'                                         
  783.                     '(' argument.expression.list ')'  
  784.         | '(' paren.typedef.declarator ')' postfixing.abstract.declarator        
  785.                    '(' argument.expression.list ')'  
  786.         | '(' simple.paren.typedef.declarator postfixing.abstract.declarator ')' 
  787.                    '(' argument.expression.list ')'  
  788.         | '(' TYPEDEFname postfixing.abstract.declarator ')'                     
  789.                    '(' argument.expression.list ')'  
  790.         ;
  791.  
  792. constructed.parameter.typedef.declarator:
  793.         TYPEDEFname    '(' argument.expression.list ')' 
  794.         | TYPEDEFname postfixing.abstract.declarator                       
  795.                        '(' argument.expression.list ')'  /* semantic error */
  796.         | '(' clean.typedef.declarator ')'                                 
  797.                        '(' argument.expression.list ')'
  798.         | '(' clean.typedef.declarator ')'  postfixing.abstract.declarator
  799.                        '(' argument.expression.list ')'
  800.         ;
  801.  
  802.  
  803.  
  804. constructed.identifier.declarator:
  805.         nonunary.constructed.identifier.declarator
  806.         | indirect.or.reference constructed.identifier.declarator
  807.         | pointer.operator      constructed.identifier.declarator
  808.         ;
  809.  
  810.     /*  The  following  are  restricted to NOT begin with any pointer
  811.     operators.  This includes both "*" and "T::*"  modifiers.   Aside 
  812.     from   this   restriction,   the   following   would  have  been: 
  813.     identifier.declarator '(' argument.expression.list ')' */
  814.  
  815. nonunary.constructed.identifier.declarator:
  816.         paren.identifier.declarator   '(' argument.expression.list ')'
  817.         | paren.identifier.declarator postfixing.abstract.declarator   
  818.                        '(' argument.expression.list ')'  /* semantic error*/
  819.         | '(' unary.identifier.declarator ')' 
  820.                        '(' argument.expression.list ')'
  821.         | '(' unary.identifier.declarator ')' postfixing.abstract.declarator  
  822.                        '(' argument.expression.list ')'
  823.         ;
  824.  
  825.  
  826. declaration.specifier:
  827.         basic.declaration.specifier        /* Arithmetic or void */
  828.         | sue.declaration.specifier          /* struct/union/enum/class */
  829.         | typedef.declaration.specifier      /* typedef*/
  830.         ;
  831.  
  832. type.specifier:
  833.         basic.type.specifier                 /* Arithmetic or void */
  834.         | sue.type.specifier                 /* Struct/Union/Enum/Class */
  835.         | typedef.type.specifier             /* Typedef */
  836.         ;
  837.  
  838.  
  839. declaration.qualifier.list:  /* storage class and optional const/volatile */
  840.         storage.class
  841.         | type.qualifier.list storage.class
  842.         | declaration.qualifier.list declaration.qualifier
  843.         ;
  844.  
  845. type.qualifier.list:
  846.         type.qualifier
  847.         | type.qualifier.list type.qualifier
  848.         ;
  849.  
  850. declaration.qualifier:
  851.         type.qualifier                  /* const or volatile */
  852.         | storage.class
  853.         ;
  854.  
  855. type.qualifier:
  856.         CONST
  857.         | VOLATILE
  858.         ;
  859.  
  860. basic.declaration.specifier:      /*Storage Class+Arithmetic or void*/
  861.         basic.type.specifier  storage.class
  862.         | basic.type.name     storage.class
  863.         | declaration.qualifier.list basic.type.name
  864.         | basic.declaration.specifier declaration.qualifier
  865.         | basic.declaration.specifier basic.type.name
  866.         ;
  867.  
  868. basic.type.specifier:
  869.         basic.type.name        basic.type.name /* Arithmetic or void */
  870.         | basic.type.name      type.qualifier
  871.         | type.qualifier.list  basic.type.name
  872.         | basic.type.specifier type.qualifier
  873.         | basic.type.specifier basic.type.name
  874.         ;
  875.  
  876. sue.declaration.specifier:          /* Storage Class + struct/union/enum/class */
  877.         sue.type.specifier storage.class
  878.         | declaration.qualifier.list elaborated.type.name
  879.         | sue.declaration.specifier declaration.qualifier
  880.         ;
  881.  
  882. sue.type.specifier:
  883.         elaborated.type.name              /* struct/union/enum/class */
  884.         | type.qualifier.list elaborated.type.name
  885.         | sue.type.specifier type.qualifier
  886.         ;
  887.  
  888.  
  889. typedef.declaration.specifier:       /*Storage Class + typedef types */
  890.         typedef.type.specifier storage.class
  891.         | TYPEDEFname          storage.class
  892.         | declaration.qualifier.list TYPEDEFname
  893.         | typedef.declaration.specifier declaration.qualifier
  894.         ;
  895.  
  896. typedef.type.specifier:              /* typedef types */
  897.         TYPEDEFname              type.qualifier
  898.         | type.qualifier.list    TYPEDEFname
  899.         | typedef.type.specifier type.qualifier
  900.         ;
  901.  
  902.     /* There are really several  distinct  sets  of  storage.classes.  
  903.     The  sets  vary  depending  on whether the declaration is at file 
  904.     scope, is a  declaration  within  a  struct/class,  is  within  a 
  905.     function body, or in a function declaration/definition (prototype 
  906.     parameter  declarations).  They  are grouped here to simplify the 
  907.     grammar,  and  can  be  semantically  checked.   Note  that  this 
  908.     approach  tends to ease the syntactic restrictions in the grammar 
  909.     slightly, but allows for future language development,  and  tends 
  910.     to  provide  superior  diagnostics  and  error  recovery (i.e.: a 
  911.     syntax error does not disrupt the parse).
  912.  
  913.  
  914.                 File    File    Member  Member  Local   Local  Formal
  915.                 Var     Funct   Var     Funct   Var     Funct  Params
  916. TYPEDEF         x       x       x       x       x       x
  917. EXTERN          x       x                       x       x
  918. STATIC          x       x       x       x       x
  919. AUTO                                            x              x
  920. REGISTER                                        x              x
  921. FRIEND                                  x       
  922. OVERLOAD                x               x               x
  923. INLINE                  x               x               x
  924. VIRTUAL                                 x               x
  925. */
  926.  
  927. storage.class:
  928.         TYPEDEF 
  929.         | EXTERN
  930.         | STATIC 
  931.         | AUTO
  932.         | REGISTER
  933.         | FRIEND   /* C++, not ANSI C */
  934.         | OVERLOAD /* C++, not ANSI C */
  935.         | INLINE   /* C++, not ANSI C */
  936.         | VIRTUAL  /* C++, not ANSI C */
  937.         ;
  938.  
  939. basic.type.name:
  940.         VOID
  941.         | CHAR
  942.         | SHORT
  943.         | INT
  944.         | LONG
  945.         | FLOAT
  946.         | DOUBLE
  947.         | SIGNED
  948.         | UNSIGNED
  949.         ;
  950.  
  951. elaborated.type.name:
  952.         aggregate.name
  953.         | enum.name
  954.         ;
  955.  
  956.  
  957.     /* Since the expression "new type.name" MIGHT use  an  elaborated 
  958.     type  and a derivation, it MIGHT have a ':'.  This fact conflicts 
  959.     with the requirement that a new expression can be placed  between 
  960.     a '?' and a ':' in a conditional expression (at least it confuses 
  961.     most LR(1) parsers). */
  962.  
  963.     /*  The derivation.opt reduction was placed DELIBERATELY in front 
  964.     of aggregate.name to resolve  a  reduce-reduce  on  '{'  conflict 
  965.     properly */
  966.     
  967. derivation.opt:
  968.         /* nothing */
  969.         | ':' derivation.list
  970.         ;
  971.  
  972.     /*  The  intermediate  actions  {}  represent points at which the 
  973.     database of typedef names  must  be  updated  in  C++.   This  is 
  974.     critical to the lexer, which must begin to tokenize based on this 
  975.     new information. */
  976.  
  977. aggregate.name:
  978.         aggregate.key                             derivation.opt {}
  979.                 '{' member.declaration.list.opt '}'
  980.         | aggregate.key identifier.or.typedef.name derivation.opt  {}
  981.                 '{' member.declaration.list.opt '}'
  982.         | aggregate.key identifier.or.typedef.name                 {}
  983.         ;
  984.  
  985. derivation.list:
  986.         parent.class
  987.         | derivation.list ',' parent.class
  988.         ;
  989.  
  990. parent.class:
  991.         TYPEDEFname
  992.         | VIRTUAL access.specifier.opt TYPEDEFname
  993.         | access.specifier virtual.opt TYPEDEFname
  994.         ;
  995.  
  996. virtual.opt:
  997.         /* nothing */
  998.         | VIRTUAL
  999.         ;
  1000.  
  1001. access.specifier.opt:
  1002.         /* nothing */
  1003.         | access.specifier
  1004.         ;
  1005.  
  1006. access.specifier:
  1007.         PUBLIC
  1008.         | PRIVATE
  1009.         | PROTECTED /* not syntactically valid, but nice for error reporting*/
  1010.         ;
  1011.  
  1012. aggregate.key:
  1013.         STRUCT
  1014.         | UNION
  1015.         | CLASS /* C++, not ANSI C */
  1016.         ;
  1017.  
  1018.     /* Note that an empty list is ONLY allowed under C++. The grammar 
  1019.     can  be modified so that this stands out.  The trick is to define 
  1020.     member.declaration.list, and have that referenced for non-trivial 
  1021.     lists. */
  1022.  
  1023. member.declaration.list.opt:
  1024.         /* nothing */ 
  1025.         | member.declaration.list.opt member.declaration
  1026.         ;
  1027.  
  1028. member.declaration:
  1029.         member.declaring.list ';'
  1030.         | member.default.declaring.list ';'
  1031.         | PUBLIC ':'                      /* C++, not ANSI C */
  1032.         | PRIVATE ':'                     /* C++, not ANSI C */
  1033.         | PROTECTED ':'                   /* C++, not ANSI C */
  1034.         | new.function.definition         /* C++, not ANSI C */
  1035.         | constructor.function.in.class   /* C++, not ANSI C */
  1036.         | destructor.function             /* C++, not ANSI C */
  1037.         | sue.type.specifier ';'       /* nested tag elaborations*/ /* C++, not ANSI C */
  1038.         | class.rescoped.identifier ';' /*access modification*/     /* C++, not ANSI C */
  1039.         | typedef.declaration.specifier ';' /* friend T */   /* C++, not ANSI C */
  1040.         | sue.declaration.specifier ';'  /* friend class C*/  /* C++, not ANSI C */
  1041.         ;
  1042.  
  1043. member.default.declaring.list:        /* doesn't redeclare typedef*/
  1044.         type.qualifier.list          
  1045.                 identifier.declarator member.pure.opt
  1046.         | declaration.qualifier.list 
  1047.                 identifier.declarator member.pure.opt /* C++, not ANSI C */
  1048.         | member.default.declaring.list ',' 
  1049.                 identifier.declarator member.pure.opt
  1050.  
  1051.         | type.qualifier.list           bit.field.identifier.declarator 
  1052.         | declaration.qualifier.list    bit.field.identifier.declarator /* C++, not ANSI C */
  1053.         | member.default.declaring.list ','  bit.field.identifier.declarator 
  1054.         ;
  1055.  
  1056. member.declaring.list:        /* Can possibly redeclare typedefs */
  1057.         type.specifier     declarator member.pure.opt
  1058.         | basic.type.name  declarator member.pure.opt
  1059.         | member.conflict.declaring.item
  1060.  
  1061.         | member.declaring.list ',' declarator member.pure.opt
  1062.  
  1063.         | type.specifier        bit.field.declarator 
  1064.         | basic.type.name       bit.field.declarator 
  1065.         | TYPEDEFname           bit.field.declarator 
  1066.         | declaration.specifier bit.field.declarator /* C++? not ANSI C */
  1067.         | member.declaring.list ',' bit.field.declarator 
  1068.         ;
  1069.  
  1070.     /* The following conflict with constructors-
  1071.       member.conflict.declaring.item:
  1072.         TYPEDEFname           declarator member.pure.opt
  1073.         | declaration.specifier declarator member.pure.opt /* C++, not ANSI C * /
  1074.         ;
  1075.     so we inline expand declarator to get the following productions...
  1076.     */
  1077. member.conflict.declaring.item:
  1078.         TYPEDEFname             identifier.declarator            member.pure.opt
  1079.         | TYPEDEFname           parameter.typedef.declarator     member.pure.opt
  1080.         | declaration.specifier identifier.declarator            member.pure.opt
  1081.         | declaration.specifier parameter.typedef.declarator     member.pure.opt
  1082.         | TYPEDEFname           simple.paren.typedef.declarator  member.pure.opt
  1083.         | declaration.specifier simple.paren.typedef.declarator  member.pure.opt
  1084.  
  1085.         | member.conflict.paren.declaring.item
  1086.         ;
  1087.  
  1088.     /* The following still conflicts with constructors-
  1089.       member.conflict.paren.declaring.item:
  1090.         TYPEDEFname           paren.typedef.declarator     member.pure.opt
  1091.         | declaration.specifier paren.typedef.declarator     member.pure.opt
  1092.         ;
  1093.     so paren.typedef.declarator is expanded inline to get...*/
  1094.  
  1095. member.conflict.paren.declaring.item:
  1096.         TYPEDEFname   indirect.or.reference 
  1097.                 '(' simple.paren.typedef.declarator ')' member.pure.opt
  1098.         | TYPEDEFname pointer.operator
  1099.                 '(' simple.paren.typedef.declarator ')' member.pure.opt
  1100.         | TYPEDEFname indirect.or.reference
  1101.                 '(' TYPEDEFname ')'                     member.pure.opt
  1102.         | TYPEDEFname pointer.operator
  1103.                 '(' TYPEDEFname ')'                     member.pure.opt
  1104.         | TYPEDEFname indirect.or.reference
  1105.                  paren.typedef.declarator               member.pure.opt
  1106.         | TYPEDEFname pointer.operator
  1107.                  paren.typedef.declarator               member.pure.opt
  1108.         | declaration.specifier indirect.or.reference
  1109.                 '(' simple.paren.typedef.declarator ')' member.pure.opt
  1110.         | declaration.specifier pointer.operator
  1111.                 '(' simple.paren.typedef.declarator ')' member.pure.opt
  1112.         | declaration.specifier indirect.or.reference
  1113.                 '(' TYPEDEFname ')'                     member.pure.opt
  1114.         | declaration.specifier pointer.operator
  1115.                 '(' TYPEDEFname ')'                     member.pure.opt
  1116.         | declaration.specifier indirect.or.reference
  1117.                 paren.typedef.declarator                member.pure.opt
  1118.         | declaration.specifier pointer.operator
  1119.                 paren.typedef.declarator                member.pure.opt
  1120.  
  1121.         | member.conflict.paren.postfix.declaring.item
  1122.         ;
  1123.  
  1124.     /* but we still have the following conflicts with constructors-
  1125.     member.conflict.paren.postfix.declaring.item:
  1126.       TYPEDEFname           paren.postfix.typedef.declarator member.pure.opt
  1127.       | declaration.specifier paren.postfix.typedef.declarator member.pure.opt
  1128.       ;
  1129.     so we expand paren.postfix.typedef inline and get...*/
  1130.  
  1131. member.conflict.paren.postfix.declaring.item:
  1132.         TYPEDEFname     '(' paren.typedef.declarator ')'
  1133.                                                            member.pure.opt
  1134.         | TYPEDEFname   '(' simple.paren.typedef.declarator
  1135.                         postfixing.abstract.declarator ')' member.pure.opt
  1136.         | TYPEDEFname   '(' TYPEDEFname
  1137.                         postfixing.abstract.declarator ')' member.pure.opt
  1138.         | TYPEDEFname   '(' paren.typedef.declarator ')'
  1139.                         postfixing.abstract.declarator     member.pure.opt
  1140.  
  1141.         | declaration.specifier '(' paren.typedef.declarator ')' 
  1142.                                                            member.pure.opt
  1143.         | declaration.specifier '(' simple.paren.typedef.declarator
  1144.                         postfixing.abstract.declarator ')' member.pure.opt
  1145.         | declaration.specifier '(' TYPEDEFname
  1146.                         postfixing.abstract.declarator ')' member.pure.opt
  1147.         | declaration.specifier '(' paren.typedef.declarator ')' 
  1148.                         postfixing.abstract.declarator     member.pure.opt
  1149.         ;
  1150.  
  1151.  
  1152. member.pure.opt:
  1153.         /* nothing */
  1154.         | '=' OCTALconstant /* C++, not ANSI C */ /* Pure function*/
  1155.         ;
  1156.  
  1157.     /* Note that bit field names cannot be parenthesized in C++  (due 
  1158.     to  ambiguities),  and  hence this part of the grammar is simpler 
  1159.     than ANSI C. :-) */
  1160.  
  1161. bit.field.declarator:
  1162.         bit.field.identifier.declarator
  1163.         | TYPEDEFname {} ':' constant.expression
  1164.         ;
  1165.  
  1166.     /* The actions taken in the "{}" above and below are probably not 
  1167.     really required (re: putting the symbol into the symbol table  as 
  1168.     part  of  the  struct), as there is (I think) no way to reference 
  1169.     them until the struct is complete.  Hence there is no  real  risk 
  1170.     that  the constant.expression would make reference to them (e.g., 
  1171.     "name : sizeof  name").   For  cleanliness,  we  will  leave  the 
  1172.     actions in this form. */
  1173.  
  1174. bit.field.identifier.declarator:
  1175.         ':' constant.expression
  1176.         | IDENTIFIER {} ':' constant.expression
  1177.         ;
  1178.  
  1179. enum.name:
  1180.         ENUM '{' enumerator.list '}'
  1181.         | ENUM identifier.or.typedef.name '{' enumerator.list '}'
  1182.         | ENUM identifier.or.typedef.name
  1183.         ;
  1184.  
  1185. enumerator.list:
  1186.         enumerator.list.no.trailing.comma
  1187.         | enumerator.list.no.trailing.comma ',' /* C++, not ANSI C */
  1188.         ;
  1189.  
  1190.     /*  Note  that we do not need to rush to add an enumerator to the 
  1191.     symbol table until *AFTER* the  enumerator.value.opt  is  parsed.  
  1192.     The  enumerated  value  is  only in scope AFTER its definition is 
  1193.     complete.  Hence the following is legal: "enum {a, b=a+10};"  but 
  1194.     the  following is (assuming no external matching of names) is not 
  1195.     legal: "enum {c, d=sizeof(d)};" ("d" not defined when sizeof  was 
  1196.     applied.)  This  is  notably  contrasted  with declarators, which 
  1197.     enter scope as soon as the declarator is complete. */
  1198.  
  1199. enumerator.list.no.trailing.comma:
  1200.         identifier.or.typedef.name enumerator.value.opt
  1201.         | enumerator.list.no.trailing.comma ',' 
  1202.                identifier.or.typedef.name enumerator.value.opt
  1203.         ;
  1204.  
  1205. enumerator.value.opt:
  1206.         /* Nothing */
  1207.         | '=' constant.expression
  1208.         ;
  1209.  
  1210.     /* We special case the lone type.name which has no storage  class 
  1211.     (even  though  it should be an example of a parameter.type.list). 
  1212.     This helped to disambiguate type-names in parenthetical casts.*/
  1213.  
  1214. parameter.type.list: 
  1215.         '(' ')'                             type.qualifier.list.opt
  1216.         | '(' type.name ')'                 type.qualifier.list.opt
  1217.         | '(' type.name initializer ')'     type.qualifier.list.opt /* C++, not ANSI C */
  1218.         | '(' named.parameter.type.list ')' type.qualifier.list.opt
  1219.         ;
  1220.     
  1221.     /* The following are used in old style function definitions, when 
  1222.     a complex return type includes the "function returning" modifier.  
  1223.     Note the  subtle  distinction  from  parameter.type.list.   These 
  1224.     parameters are NOT the parameters for the function being defined, 
  1225.     but are simply part of the type definition.  An example would be:
  1226.  
  1227.         int(*f(   a  ))(float) long a; {...}
  1228.  
  1229.     which is equivalent to the full new style definition:
  1230.  
  1231.         int(*f(long a))(float) {...}
  1232.  
  1233.     The    type    list    `(float)'    is    an    example   of   an 
  1234.     old.parameter.type.list.  The bizarre point here is that  an  old 
  1235.     function  definition  declarator  can be followed by a type list, 
  1236.     which can start with a qualifier `const'.   This  conflicts  with 
  1237.     the  new  syntactic  construct for const member functions!?! As a 
  1238.     result, an old style function definition cannot be  used  in  all 
  1239.     cases for a member function.  */
  1240.  
  1241. old.parameter.type.list: 
  1242.         '(' ')' 
  1243.         | '(' type.name ')' 
  1244.         | '(' type.name initializer ')'  /* C++, not ANSI C */
  1245.         | '(' named.parameter.type.list ')' 
  1246.         ;
  1247.  
  1248. named.parameter.type.list:  /* WARNING: excludes lone type.name*/
  1249.         parameter.list
  1250.         | parameter.list comma.opt.ellipsis
  1251.         | type.name comma.opt.ellipsis
  1252.         | type.name initializer comma.opt.ellipsis  /* C++, not ANSI C */
  1253.         | ELLIPSIS /* C++, not ANSI C */
  1254.         ;
  1255.  
  1256.  
  1257. comma.opt.ellipsis:
  1258.         ELLIPSIS       /* C++, not ANSI C */
  1259.         | ',' ELLIPSIS
  1260.         ;
  1261.  
  1262. parameter.list: 
  1263.         named.parameter.declaration
  1264.         | named.parameter.declaration initializer /* C++, not ANSI C */
  1265.         | type.name             ',' parameter.declaration
  1266.         | type.name initializer ',' parameter.declaration  /* C++, not ANSI C */
  1267.         | parameter.list ',' parameter.declaration
  1268.         ;
  1269.  
  1270.     /*  There  is  some very subtle disambiguation going on here.  Do 
  1271.     not be tempted to make further use of the following production in 
  1272.     parameter.list, or else the conflict count will grow  noticeably.  
  1273.     Specifically,  the  next  set  of  rules  has already been inline 
  1274.     expanded for the first parameter in a parameter.list to support a 
  1275.     deferred disambiguation. */
  1276.      
  1277. parameter.declaration:
  1278.         type.name
  1279.         | type.name initializer  /* C++, not ANSI C */
  1280.         | named.parameter.declaration
  1281.         | named.parameter.declaration initializer /* C++, not ANSI C */
  1282.         ;
  1283.  
  1284.     /* One big thing implemented here is that a TYPEDEFname CANNOT be 
  1285.     redeclared when we don't have declaration.specifiers! Notice that 
  1286.     when we do use a TYPEDEFname based declarator, only the "special" 
  1287.     (non-ambiguous  in  this  context)  typedef.declarator  is  used. 
  1288.     Everything else that is "missing" shows up as a type.name. */
  1289.  
  1290. named.parameter.declaration: /*have names or storage classes */
  1291.         declaration.specifier
  1292.         | declaration.specifier abstract.declarator
  1293.         | declaration.specifier identifier.declarator
  1294.         | declaration.specifier parameter.typedef.declarator
  1295.  
  1296.         | declaration.qualifier.list 
  1297.         | declaration.qualifier.list abstract.declarator
  1298.         | declaration.qualifier.list identifier.declarator
  1299.         | type.specifier identifier.declarator
  1300.         | type.specifier parameter.typedef.declarator
  1301.  
  1302.         | basic.type.name identifier.declarator
  1303.         | basic.type.name parameter.typedef.declarator
  1304.  
  1305.         | TYPEDEFname identifier.declarator
  1306.         | TYPEDEFname parameter.typedef.declarator
  1307.  
  1308.         | type.qualifier.list identifier.declarator
  1309.         ;
  1310.     
  1311. identifier.or.typedef.name:
  1312.         IDENTIFIER
  1313.         | TYPEDEFname 
  1314.         ;
  1315.  
  1316. type.name:
  1317.         type.specifier
  1318.         | basic.type.name 
  1319.         | TYPEDEFname 
  1320.         | type.qualifier.list 
  1321.  
  1322.         | type.specifier abstract.declarator
  1323.         | basic.type.name abstract.declarator
  1324.         | TYPEDEFname abstract.declarator
  1325.         | type.qualifier.list abstract.declarator
  1326.         ;
  1327.  
  1328. initializer.opt:
  1329.         /* nothing */
  1330.         | initializer
  1331.         ;
  1332.  
  1333. initializer:
  1334.         '=' initializer.group
  1335.         ;
  1336.  
  1337. initializer.group:        
  1338.         '{' initializer.list '}'
  1339.         | '{' initializer.list ',' '}'
  1340.         | assignment.expression
  1341.         ;
  1342.  
  1343. initializer.list:
  1344.         initializer.group
  1345.         | initializer.list ',' initializer.group
  1346.         ;
  1347.  
  1348.  
  1349. /* STATEMENTS */
  1350. statement:
  1351.         labeled.statement
  1352.         | compound.statement
  1353.         | expression.statement
  1354.         | selection.statement
  1355.         | iteration.statement
  1356.         | jump.statement
  1357.         ;
  1358.  
  1359. labeled.statement:
  1360.         identifier.or.typedef.name ':' statement
  1361.         | CASE constant.expression ':' statement
  1362.         | DEFAULT ':' statement
  1363.         ;
  1364.  
  1365.     /*  I sneak declarations into statement.list to support C++.  The 
  1366.     grammar is a little clumsy this  way,  but  the  violation  of  C 
  1367.     syntax is heavily localized */
  1368.  
  1369. compound.statement:
  1370.         '{' '}'
  1371.         | '{' declaration.list '}'
  1372.         | '{' statement.list '}'
  1373.         | '{' declaration.list statement.list '}'
  1374.         ;
  1375.  
  1376. declaration.list:
  1377.         declaration
  1378.         | declaration.list declaration
  1379.         ;
  1380.  
  1381. statement.list:
  1382.         statement
  1383.         | statement.list statement
  1384.         | statement.list declaration /* C++, not ANSI C */
  1385.         ;
  1386.  
  1387. expression.statement:
  1388.         expression.opt ';'
  1389.         ;
  1390.  
  1391. selection.statement:
  1392.         IF '(' expression ')' statement
  1393.         | IF '(' expression ')' statement ELSE statement
  1394.         | SWITCH '(' expression ')' statement
  1395.         ;
  1396.  
  1397. iteration.statement:
  1398.         WHILE '(' expression ')' statement
  1399.         | DO statement WHILE '(' expression ')' ';'
  1400.         | FOR '(' expression.opt ';' expression.opt ';'
  1401.                 expression.opt ')' statement
  1402.         | FOR '(' declaration        expression.opt ';'
  1403.                 expression.opt ')' statement  /* C++, not ANSI C */
  1404.         ;
  1405.  
  1406. jump.statement:
  1407.         GOTO identifier.or.typedef.name ';'
  1408.         | CONTINUE ';'
  1409.         | BREAK ';'
  1410.         | RETURN expression.opt ';'
  1411.         ;
  1412.  
  1413.  
  1414. /* EXTERNAL DEFINITIONS */
  1415.  
  1416. translation.unit:
  1417.         external.definition
  1418.         | translation.unit external.definition
  1419.         ;
  1420.  
  1421. external.definition:
  1422.         function.declaration
  1423.         | function.definition
  1424.         | declaration
  1425.         | linkage.specifier function.declaration     /* C++, not ANSI C*/
  1426.         | linkage.specifier function.definition      /* C++, not ANSI C*/
  1427.         | linkage.specifier declaration              /* C++, not ANSI C*/
  1428.         | linkage.specifier '{' translation.unit '}' /* C++, not ANSI C*/
  1429.         ;
  1430.  
  1431. linkage.specifier:
  1432.         EXTERN STRINGliteral
  1433.         ;
  1434.  
  1435.     /* Note that declaration.specifiers are left out of the following 
  1436.     function declarations.  This is something of an anomaly in C, but 
  1437.     an  unfortunately  common  coding practice.  It is also sometimes 
  1438.     necessary in C++, in instances where no  return  type  should  be 
  1439.     specified (e.g., a conversion operator).*/
  1440.  
  1441. function.declaration:
  1442.         identifier.declarator ';' /* semantically verify it is a function */
  1443.         ;
  1444.         
  1445. function.definition:
  1446.         new.function.definition
  1447.         | old.function.definition
  1448.         | constructor.function.definition
  1449.         ;
  1450.  
  1451. new.function.definition:
  1452.                                      identifier.declarator compound.statement
  1453.         | declaration.specifier      identifier.declarator compound.statement
  1454.         | type.specifier             identifier.declarator compound.statement
  1455.         | basic.type.name            identifier.declarator compound.statement
  1456.         | TYPEDEFname                identifier.declarator compound.statement
  1457.         | declaration.qualifier.list identifier.declarator compound.statement
  1458.         | type.qualifier.list        identifier.declarator compound.statement
  1459.         ;
  1460.  
  1461. old.function.definition:
  1462.                                      old.function.declarator compound.statement 
  1463.         | declaration.specifier      old.function.declarator compound.statement
  1464.         | type.specifier             old.function.declarator compound.statement
  1465.         | basic.type.name            old.function.declarator compound.statement
  1466.         | TYPEDEFname                old.function.declarator compound.statement
  1467.         | declaration.qualifier.list old.function.declarator compound.statement
  1468.         | type.qualifier.list        old.function.declarator compound.statement
  1469.  
  1470.         |                            old.function.declarator declaration.list 
  1471.                 compound.statement
  1472.         | declaration.specifier      old.function.declarator declaration.list
  1473.                 compound.statement
  1474.         | type.specifier             old.function.declarator declaration.list
  1475.                 compound.statement
  1476.         | basic.type.name            old.function.declarator declaration.list
  1477.                 compound.statement
  1478.         | TYPEDEFname                old.function.declarator declaration.list
  1479.                 compound.statement
  1480.         | declaration.qualifier.list old.function.declarator declaration.list
  1481.                 compound.statement
  1482.         | type.qualifier.list        old.function.declarator declaration.list
  1483.                 compound.statement
  1484.         ;
  1485.     
  1486.     /* I needed to add some storage class options to the constructors 
  1487.     and  destructors  (e.g.: virtual, inline, ...  ) These were added 
  1488.     using declaration.qualifier.list, but they should be semantically 
  1489.     verified to be inline or virtual ONLY. If I don't have  to  allow 
  1490.     BOTH,  then  I  COULD be explicit (and not increase ambiguities). 
  1491.     With this LR(1) grammar, I have to reduce the  list  to  standard 
  1492.     declaration.qualifier.list ASAP.*/
  1493.  
  1494. destructor.function:
  1495.         declaration.qualifier.list '~' TYPEDEFname void.opt.param.list
  1496.                         destructor.function.body
  1497.         | '~' TYPEDEFname void.opt.param.list destructor.function.body
  1498.         ;
  1499.  
  1500. void.opt.param.list:
  1501.         '('        ')' type.qualifier.list.opt
  1502.         | '(' VOID ')' type.qualifier.list.opt
  1503.         ;
  1504.  
  1505. destructor.function.body:
  1506.         compound.statement  /* an actual destructor definition */
  1507.         | ';'               /* only a destructor declaration */
  1508.         ;
  1509.  
  1510.     /*  Semantically  verify that the following identifier.declarator 
  1511.     are:
  1512.     
  1513.         TYPEDEFname :: TYPEDEFname (parameter.type.list).  
  1514.  
  1515.     We use the more general form to prevent a clash  with  a  typical 
  1516.     function  definition  (which  won't have a constructor.init.list) 
  1517.     The ONLY valid declaration qualifier is INLINE. */
  1518.  
  1519. constructor.function.definition:
  1520.                                      identifier.declarator  
  1521.                                 constructor.init.list compound.statement
  1522.         | declaration.qualifier.list identifier.declarator  
  1523.                                 constructor.init.list compound.statement
  1524.         ;
  1525.  
  1526.     /* The following use of declaration.specifiers are made to  allow 
  1527.     for  a TYPEDEFname preceded by an INLINE modifier. This fact must 
  1528.     be verified semantically.  It should also be  verified  that  the 
  1529.     TYPEDEFname  is  ACTUALLY  the  class name being elaborated. Note 
  1530.     that we could break out typedef.declaration.specifier from within 
  1531.     declaration.specifier, and we  might  narrow  down  the  conflict 
  1532.     region a bit. A second alternative (to what is done) for cleaning 
  1533.     up  this  stuff  is  to  let the tokenizer specially identify the 
  1534.     current class being elaborated as a special token, and not just a 
  1535.     typedef.name. Unfortunately, things would get very confusing  for 
  1536.     the  lexer,  as  we may pop into enclosed tag elaboration scopes; 
  1537.     into function definitions; or into both recursively! */
  1538.     
  1539. constructor.function.in.class:
  1540.         declaration.specifier   constructor.parameter.list.and.body
  1541.         | TYPEDEFname           constructor.parameter.list.and.body
  1542.         ;
  1543.  
  1544.     /* The following conflicts with member declarations-
  1545.     constructor.parameter.list.and.body:
  1546.           parameter.type.list ';'
  1547.           | parameter.type.list constructor.init.list.opt compound.statement
  1548.           ;
  1549.     so parameter.type.list was expanded inline to get */
  1550.  
  1551. constructor.parameter.list.and.body:
  1552.           '('                           ')' type.qualifier.list.opt ';'
  1553.         | '(' type.name initializer     ')' type.qualifier.list.opt ';' /* C++, not ANSI C */
  1554.         | '(' named.parameter.type.list ')' type.qualifier.list.opt ';'
  1555.         | '('                           ')' type.qualifier.list.opt
  1556.                 constructor.init.list.opt compound.statement
  1557.         | '(' type.name initializer     ')' type.qualifier.list.opt
  1558.                 constructor.init.list.opt compound.statement  /* C++, not ANSI C */
  1559.         | '(' named.parameter.type.list ')' type.qualifier.list.opt
  1560.                 constructor.init.list.opt compound.statement
  1561.         | constructor.conflicting.parameter.list.and.body
  1562.         ;
  1563.  
  1564.     /* The following conflicted with member declaration-
  1565.     constructor.conflicting.parameter.list.and.body:
  1566.         '(' type.name ')'                 type.qualifier.list.opt ';'
  1567.         | '(' type.name ')'                 type.qualifier.list.opt
  1568.                 constructor.init.list.opt compound.statement
  1569.         ;
  1570.     so type.name was inline expanded to get the following... */
  1571.  
  1572. constructor.conflicting.parameter.list.and.body:
  1573.         '(' type.specifier ')' type.qualifier.list.opt
  1574.                 ';'
  1575.         | '(' basic.type.name  ')' type.qualifier.list.opt
  1576.                 ';'
  1577.         | '(' TYPEDEFname  ')' 
  1578.                 ';'
  1579.         | '(' TYPEDEFname  ')' type.qualifier.list
  1580.                 ';'
  1581.  
  1582.         | '(' type.qualifier.list  ')' type.qualifier.list.opt
  1583.                 ';'
  1584.         | '(' type.specifier abstract.declarator ')' type.qualifier.list.opt
  1585.                 ';'
  1586.         | '(' basic.type.name abstract.declarator ')' type.qualifier.list.opt
  1587.                 ';'
  1588.         | '(' type.qualifier.list abstract.declarator ')' type.qualifier.list.opt
  1589.                 ';'
  1590.  
  1591.         | '(' type.specifier ')' type.qualifier.list.opt
  1592.                 constructor.init.list.opt compound.statement
  1593.         | '(' basic.type.name  ')' type.qualifier.list.opt
  1594.                 constructor.init.list.opt compound.statement
  1595.         | '(' TYPEDEFname  ')' 
  1596.                 constructor.init.list.opt compound.statement
  1597.         | '(' TYPEDEFname  ')' type.qualifier.list
  1598.                 constructor.init.list.opt compound.statement
  1599.  
  1600.         | '(' type.qualifier.list  ')' type.qualifier.list.opt
  1601.                 constructor.init.list.opt compound.statement
  1602.         | '(' type.specifier abstract.declarator ')' type.qualifier.list.opt
  1603.                 constructor.init.list.opt compound.statement
  1604.         | '(' basic.type.name abstract.declarator ')' type.qualifier.list.opt
  1605.                 constructor.init.list.opt compound.statement
  1606.         | '(' type.qualifier.list abstract.declarator ')' type.qualifier.list.opt
  1607.                 constructor.init.list.opt compound.statement
  1608.         | constructor.conflicting.typedef.declarator
  1609.         ;
  1610.  
  1611.  
  1612.     /* The following have ambiguities with member declarations-
  1613.     constructor.conflicting.typedef.declarator:
  1614.       '(' TYPEDEFname abstract.declarator ')' type.qualifier.list.opt
  1615.                 ';'
  1616.       |  '(' TYPEDEFname abstract.declarator ')' type.qualifier.list.opt
  1617.                 constructor.init.list.opt compound.statement
  1618.       ;
  1619.     which can be deferred by expanding abstract.declarator, and in two 
  1620.     cases parameter.qualifier.list, resulting in ...*/
  1621.  
  1622. constructor.conflicting.typedef.declarator:
  1623.         '(' TYPEDEFname unary.abstract.declarator ')' type.qualifier.list.opt
  1624.                 ';'
  1625.         | '(' TYPEDEFname unary.abstract.declarator ')' type.qualifier.list.opt
  1626.                 constructor.init.list.opt compound.statement
  1627.  
  1628.         | '(' TYPEDEFname postfix.abstract.declarator ')' type.qualifier.list.opt
  1629.                 ';'
  1630.         | '(' TYPEDEFname postfix.abstract.declarator ')' type.qualifier.list.opt
  1631.                 constructor.init.list.opt compound.statement
  1632.  
  1633.         | '(' TYPEDEFname postfixing.abstract.declarator ')' type.qualifier.list
  1634.                 ';'
  1635.         | '(' TYPEDEFname postfixing.abstract.declarator ')' type.qualifier.list
  1636.                 constructor.init.list.opt compound.statement
  1637.  
  1638.         | '(' TYPEDEFname postfixing.abstract.declarator ')' 
  1639.                 ';'
  1640.         | '(' TYPEDEFname postfixing.abstract.declarator ')' 
  1641.                 constructor.init.list.opt compound.statement
  1642.         ;
  1643.  
  1644.  
  1645. constructor.init.list.opt:
  1646.         /* nothing */
  1647.         | constructor.init.list
  1648.         ;
  1649.  
  1650. constructor.init.list:
  1651.         ':' constructor.init
  1652.         | constructor.init.list ',' constructor.init
  1653.         ;
  1654.  
  1655. constructor.init:
  1656.         identifier.or.typedef.name   '(' argument.expression.list ')'
  1657.         | identifier.or.typedef.name '('                          ')'
  1658.         | '(' argument.expression.list ')' /* Single inheritance ONLY*/
  1659.         | '(' ')' /* Is this legal? It might be default! */
  1660.         ;        
  1661.  
  1662. declarator:
  1663.         typedef.declarator
  1664.         | identifier.declarator
  1665.         ;
  1666.         
  1667. typedef.declarator:
  1668.         paren.typedef.declarator  /* would be ambiguous as parameter*/
  1669.         | simple.paren.typedef.declarator /* also ambiguous */
  1670.         | parameter.typedef.declarator   /* not ambiguous as param*/
  1671.         ;
  1672.  
  1673. parameter.typedef.declarator:
  1674.         TYPEDEFname
  1675.         | TYPEDEFname postfixing.abstract.declarator
  1676.         | clean.typedef.declarator
  1677.         ;
  1678.  
  1679.     /* The following have at  least  one  '*'or  '&'.   There  is  no 
  1680.     (redundant) '(' between the '*'/'&' and the TYPEDEFname. */
  1681.     
  1682. clean.typedef.declarator:
  1683.         clean.postfix.typedef.declarator
  1684.         | indirect.or.reference parameter.typedef.declarator
  1685.         | pointer.operator      parameter.typedef.declarator  
  1686.         ;
  1687.  
  1688. clean.postfix.typedef.declarator:
  1689.         '(' clean.typedef.declarator ')'
  1690.         | '(' clean.typedef.declarator ')' postfixing.abstract.declarator
  1691.         ;
  1692.  
  1693.     /*  The  following have a redundant '(' placed immediately to the 
  1694.     left of the TYPEDEFname */
  1695.     
  1696. paren.typedef.declarator:
  1697.         paren.postfix.typedef.declarator
  1698.         | indirect.or.reference '(' simple.paren.typedef.declarator ')'
  1699.         | pointer.operator      '(' simple.paren.typedef.declarator ')'
  1700.         | indirect.or.reference '(' TYPEDEFname ')' /* redundant paren */
  1701.         | pointer.operator      '(' TYPEDEFname ')' /* redundant paren */
  1702.         | indirect.or.reference paren.typedef.declarator
  1703.         | pointer.operator      paren.typedef.declarator
  1704.         ;
  1705.         
  1706. paren.postfix.typedef.declarator:
  1707.         '(' paren.typedef.declarator ')'
  1708.         | '(' simple.paren.typedef.declarator postfixing.abstract.declarator ')' 
  1709.         | '(' TYPEDEFname postfixing.abstract.declarator ')' /* redundant paren */
  1710.         | '(' paren.typedef.declarator ')' postfixing.abstract.declarator
  1711.         ;
  1712.  
  1713.     /* The following excludes lone TYPEDEFname to help in a  conflict 
  1714.     resolution.   We  have  special cased lone TYPEDEFname along side 
  1715.     all uses */
  1716.     
  1717. simple.paren.typedef.declarator:
  1718.         '(' TYPEDEFname ')'
  1719.         | '(' simple.paren.typedef.declarator ')'
  1720.         ;
  1721.  
  1722. identifier.declarator:
  1723.         unary.identifier.declarator  
  1724.         | paren.identifier.declarator
  1725.         ;
  1726.  
  1727.     /* The following allows "function return array  of"  as  well  as 
  1728.     "array  of  function  returning".  It COULD be cleaned up the way 
  1729.     abstract declarators have been.  This change might make  it  hard 
  1730.     to  recover from user's syntax errors, whereas now they appear as 
  1731.     simple semantic errors. */
  1732.  
  1733. unary.identifier.declarator:
  1734.         postfix.identifier.declarator
  1735.         | indirect.or.reference identifier.declarator
  1736.         | pointer.operator      identifier.declarator
  1737.         ;
  1738.  
  1739. postfix.identifier.declarator:
  1740.         paren.identifier.declarator postfixing.abstract.declarator
  1741.         | '(' unary.identifier.declarator ')'
  1742.         | '(' unary.identifier.declarator ')' postfixing.abstract.declarator
  1743.         ;
  1744.  
  1745. old.function.declarator:
  1746.         postfix.old.function.declarator
  1747.         | indirect.or.reference old.function.declarator
  1748.         | pointer.operator      old.function.declarator
  1749.         ;
  1750.  
  1751.     /* ANSI C section 3.7.1  states  "An  identifier  declared  as  a 
  1752.     typedef  name shall not be redeclared as a parameter".  Hence the 
  1753.     following is based only on IDENTIFIERs.
  1754.     
  1755.     Instead of identifier.lists, an argument.expression.list is  used 
  1756.     in   old   style   function   definitions.   The  ambiguity  with 
  1757.     constructors required the use of argument lists, with a  semantic 
  1758.     verification   of   the   list  (e.g.:  check  to  see  that  the 
  1759.     "expressions" consisted of lone identifiers).  
  1760.     
  1761.     An interesting ambiguity appeared:
  1762.         const constant=5;
  1763.         int foo(constant) ...
  1764.  
  1765.     Is this an old function definition or constructor?  The  decision 
  1766.     is made later by THIS grammar based on trailing context :-). This 
  1767.     ambiguity  is probably what caused many parsers to give up on old 
  1768.     style function definitions. */
  1769.  
  1770. postfix.old.function.declarator:
  1771.         paren.identifier.declarator '(' argument.expression.list ')'
  1772.         | '(' old.function.declarator ')'
  1773.         | '(' old.function.declarator ')' old.postfixing.abstract.declarator
  1774.         ;
  1775.  
  1776. old.postfixing.abstract.declarator:
  1777.         array.abstract.declarator /* array modifiers */
  1778.         | old.parameter.type.list  /* function returning modifiers */
  1779.         ;
  1780.  
  1781. abstract.declarator:
  1782.         unary.abstract.declarator
  1783.         | postfix.abstract.declarator
  1784.         | postfixing.abstract.declarator
  1785.         ;
  1786.  
  1787. postfixing.abstract.declarator:
  1788.         array.abstract.declarator
  1789.         | parameter.type.list
  1790.         ;
  1791.  
  1792. array.abstract.declarator:
  1793.         '[' ']'
  1794.         | '[' constant.expression ']'
  1795.         | array.abstract.declarator '[' constant.expression ']'
  1796.         ;
  1797.  
  1798. unary.abstract.declarator:
  1799.         indirect.or.reference 
  1800.         | pointer.operator 
  1801.         | indirect.or.reference abstract.declarator
  1802.         | pointer.operator      abstract.declarator
  1803.         ;
  1804.  
  1805. postfix.abstract.declarator:
  1806.         '(' unary.abstract.declarator ')'
  1807.         | '(' postfix.abstract.declarator ')'
  1808.         | '(' postfixing.abstract.declarator ')'
  1809.         | '(' unary.abstract.declarator ')' postfixing.abstract.declarator
  1810.         ;
  1811.  
  1812. indirect.or.reference:
  1813.         '*'
  1814.         | '&'
  1815.         ;
  1816.  
  1817. pointer.operator:
  1818.         TYPEDEFname CLCL '*' type.qualifier.list.opt
  1819.         | indirect.or.reference type.qualifier.list
  1820.         ;
  1821. %%
  1822. yyerror(string)
  1823. char*string;
  1824. {
  1825.     printf("parser error: %s\n", string);
  1826. }
  1827.  
  1828.  
  1829. main()
  1830. {
  1831.     yyparse();
  1832. }
  1833.